﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CsvHelper;
namespace InverseTree
{
    partial class Program
    {
        public static Dictionary<int, Node> records = new Dictionary<int, Node>();
        static void Main(string[] args)
        {
            using (var reader = new StreamReader(@"D:\VSCode\AlgorithmExercises\InverseTree\Input.csv"))
            using (var csv = new CsvReader(reader))
            {
                records = csv.GetRecords<Node>().ToDictionary(k => k.Id, v => v);
            }

            CheckAll(records.Values.FirstOrDefault());


            using (var writer = new StreamWriter(@"D:\VSCode\AlgorithmExercises\InverseTree\Input.csv"))
            using (var csv = new CsvWriter(writer))
            {
                csv.WriteRecords<Node>(records.Values.ToList());
            }

            InverseTree(records.Values.FirstOrDefault());

            using (var writer = new StreamWriter(@"D:\VSCode\AlgorithmExercises\InverseTree\Output.csv"))
            using (var csv = new CsvWriter(writer))
            {
                csv.WriteRecords<Node>(records.Values.ToList());
            }

            Console.WriteLine(records.Count);
        }

        /// <summary>
        /// 检查所有节点 补全所有出现的叶子节点Id 到字典中
        /// </summary>
        private static void CheckAll(Node root)
        {
            if (root == null)
            {
                return;
            }
            if (root.LeftChild != null)
            {
                if (!records.ContainsKey(root.LeftChild.Value))
                    records.Add(root.LeftChild.Value, new Node() { Id = root.LeftChild.Value, Value = root.LeftChild.Value });
                CheckAll(root.GetLeftChildNode());
            }
            if (root.RightChild != null)
            {
                if (!records.ContainsKey(root.RightChild.Value))
                    records.Add(root.RightChild.Value, new Node() { Id = root.RightChild.Value, Value = root.RightChild.Value });
                CheckAll(root.GetRightChildNode());
            }
        }

        /// <summary>
        /// 反转左右子节点
        /// </summary>
        /// <param name="root"></param>
        private static void InverseTree(Node root)
        {
            if (root == null)
                return;
            if (root.LeftChild != null && root.RightChild != null)
            {
                root.LeftChild = root.LeftChild + root.RightChild;
                root.RightChild = root.LeftChild - root.RightChild;
                root.LeftChild = root.LeftChild - root.RightChild;
            }
            else
            {
                int? tmp = root.LeftChild;
                root.LeftChild = root.RightChild == null ? null : root.RightChild;
                root.RightChild = tmp == null ? null : tmp;
            }

            InverseTree(root.GetLeftChildNode());
            InverseTree(root.GetRightChildNode());
        }

        private static void Swap(ref int? a, ref int? b)
        {
            if (a != null && b != null)
            {
                a = a + b;
                b = a - b;
                a = a - b;
            }
            else
            {
                int? tmp = a;
                a = b == null ? null : b;
                b = tmp == null ? null : tmp;
            }

        }
    }
}
